Трансформация Бокса-Кокса позволяет привести данные к нормальному распределению. Проблема возникает в тот момент, когда мы представляем результаты заказчику. Если у нас целевая переменная - рубли, то трансформация превращает рубли в непонятно во что. И после обучения модели, в уже промышленном применения, нам необходима обратная трансформация из Бокса-Кокса в рубли.
Я нигде не нашел полного поста, как это делается (может просто я не там искал), но решил сделать пост с инструкцией по обратной трансформации Бокса - Кокса.
Итак
Необходимый пакет
library(caret)Создаем данные
set.seed(1)
a = rnorm(100, mean = 80, sd = 40)
b = rnorm(200, mean = 40, sd =20)
c = c(a,b)
df = as.data.frame(c)
df = subset(df, df$c > 0) # удаляем значение менее нуля
summary(df)
c
Min. : 0.4259
1st Qu.: 33.3343
Median : 48.8389
Mean : 56.0041
3rd Qu.: 74.5428
Max. :176.0647
hist(df$c)Данные создаем так, чтобы они были не нормально распределены. У вас будут свои данные.
shapiro.test(df$c) Shapiro-Wilk normality test data: df$c W = 0.93822, p-value = 9.752e-10Результаты теста нас вполне устраивают: данные далеки от нормальных. Теперь сама трансформация
trans = BoxCoxTrans(df$c) # задаем правило трансформации transc = predict(trans, df$c) # трансофрмируем hist(transc) # смотрим, что получилось
shapiro.test(transc) Shapiro-Wilk normality test data: transc W = 0.99504, p-value = 0.465Трансформация Бокса-Кокса получилась успешной. Что бывает далеко не всегда: очень часто трансформация Бокса-Кокса не превращает распределение в нормальное.
Обратная трансформация Бокса-Бокса
Нас интересует обратная трансформация Бокса-Кокса. Например, мы получили прогноз регрессии по трансформированным данным, нам необходимо получить значения в первоначальной переменной.Для начала узнаем лямбу (коэффициент трансформации) Бокса-Кокса. Ее можно узнать в правиле трансформации.
trans
Box-Cox Transformation
294 data points used to estimate Lambda
Input data summary:
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.4259 33.3300 48.8400 56.0000 74.5400 176.1000
Largest/Smallest: 413
Sample Skewness: 0.956
Estimated Lambda: 0.4
Лямбда = 0.4
Формула трансформации Бокса-Кокса такова
y = (x^lmbda - 1) / lmbdaИз этой формулы мы получаем формулу обратной трансформации Бокса-Кокса
x = (y*lmbda + 1)^(1/lmbda)ВАЖНО; эта формула корректна для лямбды не равной нулю. Если ламбда принимает значение 0, то преобразование Бокса-Кокса представляет логарифмирование, а обратная трансформация Бокса-Кокса, следовательно, экспонирование, т.е.
x = exp(y)Давайте проверим корректность трансформации для нашего случая
lmbda=0.4
y = transc
x = (y*lmbda + 1)^(1/lmbda)
summary(x)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.4259 33.3300 48.8400 56.0000 74.5400 176.1000
Данные обратной трансформации Бокса-Кокса не идентичны данных первоначального набора данных df$c, но различия в пределах сотых: в оригинальном датасете, например, максимальное значение 176.06, в датасете обратной трансформации Бокса-Кокса 176.1.Думаю, что нас устроит такая погрешность.


Простое и понятное объяснение с примером кода! Сейчас попробую! Спасибо!
ОтветитьУдалить